package r25.engine;

import java.util.List;
import java.util.Map;

import r25.board.IBoard;
import r25.character.ICharacter;
import r25.room.IRoom;

public interface IGameService {
	public enum GAME_PHASE {
		PROGRAM_ACTIONS, PLAY_ACTIONS
	}

	public enum CHARACTER_ROLE {
		PRISONER, GUARD
	}

	public enum GAME_MODE {
		// @formatter:off
		SOLO("Solo", 1, 1, true, 8, false), 
		TEAM("Team", 4, 6, true, 10, true), 
		SUSPICION("Suspicion", 4, 6, false, 10, true), 
		COOPERATION("Cooperation", 2, 6, false, 8, true), 
		COMPETITION("Competition", 2, 3, true, 10, true);
		// @formatter:on

		private final String name;
		private final int fromPlayers;
		private final int toPlayers;
		private final boolean exactPlayers;
		private final int maxTurn;
		private final boolean programActions;

		GAME_MODE(String name, int fromPlayers, int toPlayers,
				boolean exactPlayers, int maxTurn, boolean programActions) {
			this.name = name;
			this.fromPlayers = fromPlayers;
			this.toPlayers = toPlayers;
			this.exactPlayers = exactPlayers;
			this.maxTurn = maxTurn;
			this.programActions = programActions;
		}

		public String getName() {
			return name;
		}

		public int getFromPlayers() {
			return fromPlayers;
		}

		public int getToPlayers() {
			return toPlayers;
		}

		public boolean isExactPlayers() {
			return exactPlayers;
		}

		public int getMaxTurn() {
			return maxTurn;
		}

		public boolean hasToProgramActions() {
			return programActions;
		}
	}

	/* configuration methods */

	public abstract void configure(Map<Object, Object> map) throws Exception;

	public abstract List<IRoom> getCompositionRooms();

	public abstract List<ICharacter> getCompositionCharacters();

	public abstract Composition getComposition(String name);

	public abstract List<String> getCompositions();

	/* setup methods */

	public abstract IRoom getRoomInstance(String name);

	public abstract IBoard setupBoardInstance(String name) throws Exception;

	public abstract IGameInstance startGameInstance(String name,
			GAME_MODE mode, List<String> players) throws Exception;

	public abstract void release();

	/* random helpers */

	public abstract IRoom pickRandomRoom(List<IRoom> rooms);

	public abstract ICharacter pickRandomCharacter(List<ICharacter> l);

	/* setup players & characters helpers */

	public abstract List<Integer> computePlayerDistribution(GAME_MODE mode,
			int np, int nc);

	public abstract List<Integer> computePossibleNumberOfPlayers(GAME_MODE mode);

	public abstract int computeNumberOfCharactersPerPlayer(GAME_MODE mode,
			int np);

	public abstract int computeNumberOfGuards(GAME_MODE mode, int np);

}
